<?php

namespace App\Http\Controllers\Traits;

use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

trait Resource
{
    use IndexResource,
        StoreResource,
        ShowResource,
        UpdateResource,
        DestroyResource;

    /**
     * @var Resource $key
     */
    protected $key;

    /**
     * @var Resource $field
     */
    protected $field;

    /**
     * @var Resource model
     */
    protected $model;

    /**
     * @var Resource transformer
     */
    protected $transformer;

    /**
     * Validate and get Validated inputs
     *
     * @param  array  $rules
     * @param  array  $attributes
     *
     * @return array
     * @throws ValidationException
     */
    protected function validatedAndGetInput(array $rules, array $attributes = []) :array
    {
        return $this->validate(request(), $rules, [], $attributes);
    }

    /**
     * Get current resource object
     *
     * @return mixed
     */
    protected function getResourceFromRoute()
    {
        return $this->model->select($this->field)->find(
            $this->getResourceKey()
        );
    }

    /**
     * Throw a exception
     *
     * @param $message
     */
    public function abort($message)
    {
        throw new BadRequestHttpException($message);
    }

    /**
     * Get resource key from router
     *
     * @return \Illuminate\Routing\Route|object|string
     */
    protected function getResourceKey()
    {
        //todo lumen不能直接request()->route('test')和request('test') 不用加载所有路由加速？
        return request()->route()[2][$this->getKey()];
    }

    /**
     * Get resource key
     *
     * @return Resource|string
     */
    protected function getKey()
    {
        return $this->key ?? strtolower(class_basename($this->model));
    }

    /**
     * Trying to call a method
     *
     * @param  string  $method
     * @param  mixed  ...$var
     */
    protected function try(string $method, ...$var)
    {
        if ( ! $this->hasMethod($method)) {
            return current($var);
        }

        return $this->$method(...$var) ?? current($var);
    }

    /**
     * If I have this method
     *
     * @param  string  $method
     *
     * @return bool
     */
    protected function hasMethod(string $method): bool
    {
        return in_array($method, get_class_methods(static::class));
    }

}
